# -*- coding: UTF-8 -*-
# 2023/11/26 23:32
import os
from concurrent.futures import ThreadPoolExecutor

import requests
from retry import retry

from tools.get_configer import my_configer
from tools.get_logger import get_logger

configer = my_configer()
loger = get_logger()


def __get_img_info_list(response):
    _img_info_list = list()
    for img_info in response["res"]["vertical"]:
        img_dict = dict()
        img_dict["img_id"] = img_info["id"]
        img_dict["img_tag"] = "-".join(img_info["tag"])
        if img_info["tag"]:  # 存在tag是空情况
            img_dict["img_name"] = f'{"_".join(img_info["tag"])}_{img_info["id"]}.jpg'
        else:
            img_dict["img_name"] = f'{img_info["id"]}.jpg'

        img_dict["img_urls"] = dict()
        img_dict["img_urls"]["thumb"] = img_info["thumb"]  # 预览350*540
        img_dict["img_urls"]["img"] = img_info["img"],  # 标准大小1080*1920
        img_dict["img_urls"]["preview"] = img_info["preview"]  # 最大2000*3000,存在损坏的

        _img_info_list.append(img_dict)

    return _img_info_list


class phone_tool:
    def __init__(self):
        self.get_class()

    def get_class(self):
        """
        请求并处理后返回手机图片对应分类id和名称,后根据获取的分类获取每个分类下第一张图的最小尺寸做为封面图返回
        返回
        """
        # 请求分类预处理分类结果
        class_url = "http://service.picasso.adesk.com/v1/vertical/category?limit=30&skip=30&adult=false&first=1&order=hot"
        response = requests.get(class_url).json()
        loger.info(f"手机壁纸请求分类结果:{response}")

        # 截取所有关键信息
        self.class_id_cover_url_name_save_path_list = [[class_info["id"], class_info["cover"], class_info["name"], os.path.abspath(f"./cache/phone_cover/{class_info['id']}.jpg")] for class_info in response["res"]["category"]]

        loger.info(f"手机壁纸分类处理结果:{self.class_id_cover_url_name_save_path_list}")

        with ThreadPoolExecutor(max_workers=8) as phone_cover_pool:
            for class_id_cover_url_name_save_path in self.class_id_cover_url_name_save_path_list:
                class_id = class_id_cover_url_name_save_path[0]
                cover_url = class_id_cover_url_name_save_path[1]
                class_name = class_id_cover_url_name_save_path[2]
                save_path = class_id_cover_url_name_save_path[3]

                if not os.path.isfile(save_path):
                    # 下载封面
                    download_cover_img_future = phone_cover_pool.submit(self.download_img, cover_url, save_path)
                    setattr(download_cover_img_future, "class_id", class_id)
                    setattr(download_cover_img_future, "cover_url", cover_url)
                    setattr(download_cover_img_future, "class_name", class_name)
                    setattr(download_cover_img_future, "save_path", save_path)
                    loger.info(f"[{class_id, class_name}]提交下载, 保存位置:{save_path}, url:{cover_url}")

                    # 设置线程回调
                    download_cover_img_future.add_done_callback(self.download_cover_img_future_callback)

                else:
                    loger.info(f"[{class_id, class_name}]封面已下载跳过, 保存位置:{save_path}, url:{cover_url}")

            phone_cover_pool.shutdown(wait=True)  # 等待所有线程结束

    @retry(tries=5)
    def download_img(self, url: str, save_path: str) -> None:
        """
        根据传入的图片地址,进行下载
        :param self:
        :param url: 图片url
        :param save_path: 保存路径
        :return:
        """

        r = requests.get(url)
        response = r.content

        with open(save_path, "wb") as f:
            f.write(response)

        r.close()

        loger.info(f"图片保存成功,保存位置:{save_path},图片url:{url}")

    def download_cover_img_future_callback(self, task_future):
        task_future_result = task_future.result()
        class_id = getattr(task_future, "class_id")
        class_name = getattr(task_future, "class_name")
        cover_url = getattr(task_future, "cover_url")
        save_path = getattr(task_future, "save_path")

        try:
            # 如果返回None表示下载成功,更新对应按钮图片
            if task_future_result is None:
                loger.info(f"下载分类线程回调,分类:[{class_name}, {class_id}],保存位置:{save_path},图片url:{cover_url}")

        except:
            task_future_exception = task_future.exception()
            loger.error(f"下载分类线程回调线程遇到错误,报错信息为:{type(task_future_exception)},分类:[{class_name}, {class_id}],保存位置:{save_path},图片url:{cover_url}")


def get_page_img(class_id: str, page_num: int, skip_no: int):
    """
    根据类别id和页码获取对应分页所有图片地址
    :param class_id: 分类id
    :param page_num: 每页数量数
    :param skip_no: 跳过页数
    :return: 返回图片信息,其中thumb是预览图,
    """

    def _get_page_img(_skip_no):
        skip_sum = _skip_no * page_num
        class_page_url = f"http://service.picasso.adesk.com/v1/vertical/category/{class_id}/vertical?limit={page_num}&skip={skip_sum}&adult=false&first=1&url=http://service.picasso.adesk.com/v1/vertical/category/4e4d610cdf714d2966000003/vertical&order=new"

        response = requests.get(class_page_url).json()
        loger.info(f"指定分类按页请求 分类ID:{class_id},每页{page_num}张,从{skip_sum}张起,url:{class_page_url}, 当页请求结果:{response}")

        _page_img_info_list = __get_img_info_list(response)

        loger.info(f"分页请求,分类ID:{class_id},每页{page_num}张,从{skip_sum}起当页最终处理分类请求结果:{_page_img_info_list}")

        nonlocal all_page_img_info_list
        all_page_img_info_list += _page_img_info_list

    all_page_img_info_list = list()
    _get_page_img(skip_no * 3)
    _get_page_img(skip_no * 3 + 1)
    _get_page_img(skip_no * 3 + 2)

    loger.info(f"获取分类下图片最终请求结果,分类ID:{class_id},每页40张,从{skip_no * page_num * 3}起当前页最终处理分类请求结果:{all_page_img_info_list}")

    return all_page_img_info_list


def get_new_img(page_num: int, skip_no: int):
    """
    根据接口返回指定数量的最新壁纸
    :param page_num: 每页数量
    :param skip_no: 跳过页数
    """

    def _get_new_img(_skip_no):
        skip_sum = _skip_no * page_num
        if _skip_no == 0:
            skip_sum = 40
        nonlocal new_img_info_list

        new_url = f"http://service.picasso.adesk.com/v1/vertical/vertical?limit={page_num}&skip={skip_sum}&adult=false&first=1&order=new"
        response = requests.get(new_url).json()
        loger.info(f"分页请求最新壁纸,每页{page_num}张,从{skip_sum}起当页请求结果:{response}")

        _new_img_info_list = __get_img_info_list(response)
        loger.info(f"分页请求最新壁纸,每页{page_num}张,从{skip_sum}起当页处理结果:{_new_img_info_list}")
        new_img_info_list += _new_img_info_list

    new_img_info_list = list()
    _get_new_img(skip_no * 3)
    _get_new_img(skip_no * 3 + 1)
    _get_new_img(skip_no * 3 + 2)

    loger.info(f"请求最新壁纸,每页{page_num}张,从{skip_no * page_num * 3}起当前页最终处理分类请求结果:{new_img_info_list}")

    return new_img_info_list


def get_hot_img(page_num: int, skip_no: int):
    """
    根据接口返回指定数量的最新壁纸
    :param page_num: 每页数量
    :param skip_no: 跳过页数
    """

    def _get_new_img(_skip_no):
        skip_sum = _skip_no * page_num
        nonlocal hot_img_info_list
        hot_url = f"http://service.picasso.adesk.com/v1/vertical/vertical?limit={page_num}&skip={skip_sum}&adult=false&first=1&order=hot"
        response = requests.get(hot_url).json()
        loger.info(f"分页请求热门壁纸,每页{page_num}张,从{skip_sum}起当页请求结果:{response}")

        _hot_img_info_list = __get_img_info_list(response)
        loger.info(f"分页请求热门壁纸,每页{page_num}张,从{skip_sum}起当页处理结果:{_hot_img_info_list}")

        hot_img_info_list += _hot_img_info_list

    hot_img_info_list = list()
    _get_new_img(skip_no * 3)
    _get_new_img(skip_no * 3 + 1)
    _get_new_img(skip_no * 3 + 2)

    loger.info(f"热门壁纸,每页{page_num}张,从{page_num * skip_no * 3}起当前页最终处理分类请求结果:{hot_img_info_list}")
    return hot_img_info_list


def get_search_img(page_num: int, skip_no: int, search_keywords: str):
    """
    根据接口返回指定数量的最新壁纸
    :param page_num: 每页数量
    :param skip_no: 跳过页数
    :param search_keywords: 搜索关键字
    """

    def _get_search_img(_skip_no):
        skip_sum = _skip_no * page_num
        if _skip_no == 0:
            skip_sum = 40
        nonlocal search_img_info_list
        hot_url = f"http://so.picasso.adesk.com/v1/search/vertical/resource/{search_keywords}?limit={page_num}&channel=default&skip={skip_sum}&adult=false&first=0&order=new"
        response = requests.get(hot_url).json()
        loger.info(f"分页请求搜索壁纸关键字:{search_keywords},每页{page_num}张,从{skip_sum}起当页请求结果:{response}")

        _search_img_info_list = __get_img_info_list(response)
        loger.info(f"分页请求搜索壁纸关键字:{search_keywords},每页{page_num}张,从{skip_sum}起当前页最终处理分类请求结果:{_search_img_info_list}")

        search_img_info_list += _search_img_info_list

    search_img_info_list = list()
    _get_search_img(skip_no * 3)
    _get_search_img(skip_no * 3 + 1)
    _get_search_img(skip_no * 3 + 2)

    loger.info(f"搜索壁纸关键字:{search_keywords},每页40张,从{page_num * skip_no * 3}起最终处理分类请求结果:{search_img_info_list}")
    return search_img_info_list
